#include <stdio.h>

void length()
{
  /*4005fc:	a9bc7bfd 	stp	x29, x30, [sp, #-64]!
  400600:	910003fd 	mov	x29, sp
  400604:	90000000 	adrp	x0, 400000 <_init-0x480>
  400608:	91208000 	add	x0, x0, #0x820
  40060c:	d2800501 	mov	x1, #0x28                  	// #40 ---> 5指针，因每个指针占8个字节 (64bit系统)
  400610:	97ffffb8 	bl	4004f0 <printf@plt>*/
  printf("sizeof(*pa[5]) = %d\n", 40); 

  /*400614:	90000000 	adrp	x0, 400000 <_init-0x480>
  400618:	9120e000 	add	x0, x0, #0x838
  40061c:	d2800101 	mov	x1, #0x8                   	// #8 ---> 1个指针，占8字节 (64bit系统)
  400620:	97ffffb4 	bl	4004f0 <printf@plt>*/
  printf("sizeof((*ptr)[5]) = %d\n", 8);

  /*400624:	d503201f 	nop
  400628:	a8c47bfd 	ldp	x29, x30, [sp], #64
  40062c:	d65f03c0 	ret*/
}

void pointer_array()
{
  /*400630:	a9bc7bfd 	stp	x29, x30, [sp, #-64]!
  400634:	910003fd 	mov	x29, sp
  400638:	90000000 	adrp	x0, 400000 <_init-0x480>
  40063c:	91218001 	add	x1, x0, #0x860			// x1=0x400000+0x860
  400640:	910043a0 	add	x0, x29, #0x10			// x0=x029+0x10
  400644:	a9400c22 	ldp	x2, x3, [x1]			// x2=[x1], x3=[x1+8]	---> 1, 2, 3, 4
  400648:	a9000c02 	stp	x2, x3, [x0]			
  40064c:	a9410c22 	ldp	x2, x3, [x1, #16]		// x2=[x1+16], x3=[x1+24]	---> 5, 6, 7, 8
  400650:	a9010c02 	stp	x2, x3, [x0, #16]
  400654:	b9402021 	ldr	w1, [x1, #32]			// w1=[x1+32]	---> 9
  400658:	b9002001 	str	w1, [x0, #32]*/
  int a[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};

  /*40065c:	910043a0 	add	x0, x29, #0x10			// x0=x29+0x10
  400660:	f9001fa0 	str	x0, [x29, #56]*/		// 一个指针
  int (*ptr)[3] = a;

  /*400664:	f9401fa0 	ldr	x0, [x29, #56]			// x0=ptr
  400668:	b9400401 	ldr	w1, [x0, #4]			// w1=ptr+4 ---> 2
  40066c:	f9401fa0 	ldr	x0, [x29, #56]			// w0=ptr
  400670:	b9400802 	ldr	w2, [x0, #8]			// w2=ptr+8 ---> 3
  400674:	90000000 	adrp	x0, 400000 <_init-0x480>
  400678:	91216000 	add	x0, x0, #0x858
  40067c:	97ffff9d 	bl	4004f0 <printf@plt>*/
  printf("%d %d\n", (*ptr)[1], (*ptr)[2]);    // 2    3

  /*400680:	f9401fa0 	ldr	x0, [x29, #56]			// x0=ptr
  400684:	91003000 	add	x0, x0, #0xc			// x0=ptr+0xc
  400688:	f9001fa0 	str	x0, [x29, #56]*/		// rbp+0xc --> 跳过前三个(1,2,3)
  ++ptr;

  /*40068c:	f9401fa0 	ldr	x0, [x29, #56]			// x0=ptr ---> 4
  400690:	b9400401 	ldr	w1, [x0, #4]			// w1=ptr+4 ---> 5
  400694:	f9401fa0 	ldr	x0, [x29, #56]			// w0=ptr
  400698:	b9400802 	ldr	w2, [x0, #8]			// w2=ptr+8 ---> 6
  40069c:	90000000 	adrp	x0, 400000 <_init-0x480>
  4006a0:	91216000 	add	x0, x0, #0x858
  4006a4:	97ffff93 	bl	4004f0 <printf@plt>*/
  printf("%d %d\n", (*ptr)[1], (*ptr)[2]);    // 5    6
	
  /*4006a8:	d503201f 	nop
  4006ac:	a8c47bfd 	ldp	x29, x30, [sp], #64
  4006b0:	d65f03c0 	ret*/
}

void array_pointer()
{
  /*4006b4:	a9bb7bfd 	stp	x29, x30, [sp, #-80]!
  4006b8:	910003fd 	mov	x29, sp
  4006bc:	90000000 	adrp	x0, 400000 <_init-0x480>
  4006c0:	91218001 	add	x1, x0, #0x860
  4006c4:	9100a3a0 	add	x0, x29, #0x28		// x0=x029+0x28
  4006c8:	a9400c22 	ldp	x2, x3, [x1]		// x2=[x1], x3=[x1+8]	---> 1, 2, 3, 4
  4006cc:	a9000c02 	stp	x2, x3, [x0]
  4006d0:	a9410c22 	ldp	x2, x3, [x1, #16]	// x2=[x1+16], x3=[x1+24]	---> 5, 6, 7, 8
  4006d4:	a9010c02 	stp	x2, x3, [x0, #16]
  4006d8:	b9402021 	ldr	w1, [x1, #32]		// w1=[x1+32]	---> 9
  4006dc:	b9002001 	str	w1, [x0, #32]*/
  int a[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};

  int *pa[3];
  /*4006e0:	9100a3a0 	add	x0, x29, #0x28		// x0=0x29+x28
  4006e4:	f9000ba0 	str	x0, [x29, #16]*/	// x29+0x10=第一个指针
  pa[0] = a[0];	// 1

  /*4006e8:	9100a3a0 	add	x0, x29, #0x28		// x0=0x29+x28
  4006ec:	91003000 	add	x0, x0, #0xc
  4006f0:	f9000fa0 	str	x0, [x29, #24]*/
  pa[1] = a[1];	// 4

  /*4006f4:	9100a3a0 	add	x0, x29, #0x28
  4006f8:	91006000 	add	x0, x0, #0x18
  4006fc:	f90013a0 	str	x0, [x29, #32]*/
  pa[2] = a[2];	// 7

  /*400700:	b9004fbf 	str	wzr, [x29, #76]*/
  int i = 0;

  /*400704:	1400000c 	b	400734 <array_pointer+0x80>
  400708:	b9804fa0 	ldrsw	x0, [x29, #76]	// x0=i
  40070c:	d37df000 	lsl	x0, x0, #3			// x0=i<<3 ---> 0, 8, 16
  400710:	910043a1 	add	x1, x29, #0x10		// x1=0x29+0x10
  400714:	f8606820 	ldr	x0, [x1, x0]		// x0=[0x29+0x10+x0]
  400718:	b9400001 	ldr	w1, [x0]			// w1=x0
  40071c:	90000000 	adrp	x0, 400000 <_init-0x480>
  400720:	91222000 	add	x0, x0, #0x888
  400724:	97ffff73 	bl	4004f0 <printf@plt>
  400728:	b9404fa0 	ldr	w0, [x29, #76]		// w0=i
  40072c:	11000400 	add	w0, w0, #0x1		// w0=i+1
  400730:	b9004fa0 	str	w0, [x29, #76]	
  400734:	b9404fa0 	ldr	w0, [x29, #76]		// w0=i
  400738:	7100081f 	cmp	w0, #0x2
  40073c:	54fffe6d 	b.le	400708 <array_pointer+0x54>*/
  for(i = 0; i < 3; i++)
		printf("%d ", *pa[i]);		// 1 4 7

  /*400740:	d503201f 	nop
  400744:	a8c57bfd 	ldp	x29, x30, [sp], #80
  400748:	d65f03c0 	ret*/
}

int main()
{
  /*40074c:	a9bf7bfd 	stp	x29, x30, [sp, #-16]!
  400750:	910003fd 	mov	x29, sp
  400754:	97ffffaa 	bl	4005fc <length>*/
  length();

  /*400758:	97ffffb6 	bl	400630 <pointer_array>*/
  pointer_array();

  /*40075c:	97ffffd6 	bl	4006b4 <array_pointer>*/
  array_pointer();

  /*400760:	52800000 	mov	w0, #0x0                   	// #0
  400764:	a8c17bfd 	ldp	x29, x30, [sp], #16
  400768:	d65f03c0 	ret
  40076c:	00000000 	.inst	0x00000000 ; undefined*/
  return 0;
}
